/**
 * Candidate Number: 35834
 */

package tv.starfu.game;

import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.Trigger;
import com.jme3.renderer.RenderManager;
import de.lessvoid.nifty.Nifty;
import tv.starfu.game.states.*;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import com.artemis.EntitySystem;
import com.artemis.SystemManager;
import com.artemis.World;
import com.jme3.app.SimpleApplication;
import com.jme3.renderer.Camera;
import com.jme3.system.AppSettings;
import com.jme3.bullet.BulletAppState;
import net.beadsproject.beads.core.AudioContext;
import net.beadsproject.beads.core.Bead;
import net.beadsproject.beads.ugens.Clock;
import tv.starfu.sequencer.components.TimeVector;
import tv.starfu.sequencer.model.Sequencer;
import tv.starfu.sequencer.model.SequencerModel;
import tv.starfu.systems.ControllerSystem;
import tv.starfu.systems.InputSystem;
import tv.starfu.systems.PhysicsSystem;
import tv.starfu.systems.RenderSystem;
import tv.starfu.systems.DrumSequencerSystem;
import tv.starfu.utils.Music;

public class Main extends SimpleApplication {
    
    /* THREADS */
    private ScheduledThreadPoolExecutor executor; 
    
    /* BEADS */
    private AudioContext ac;

    
    /* SEQUENCER */
    public SequencerModel sequencerModel;
    public Sequencer sequencer;
    
    /* ARTEMIS */
    private World world;

   // private Entity player;

    /* JMONKEYENGINE */
   // private Camera cam;
    
    /* GLOBAL INPUTS */
    private Trigger arcade_trigger  = new KeyTrigger(KeyInput.KEY_RETURN);
    private Trigger grid_trigger    = new KeyTrigger(KeyInput.KEY_RSHIFT);
    private Trigger menu_trigger    = new KeyTrigger(KeyInput.KEY_L);
    private Trigger pause_trigger   = new KeyTrigger(KeyInput.KEY_BACK);
    
    /* GAME STATES */
    private ArcadeState arcadeState;
    private GridState   gridState;
    private MenuState   menuState;
    private PauseState  pauseState;
    
    /* PHYSICS */
    private BulletAppState bullet;
    
    /* NIFTY */
    private Nifty nifty;
    
    
    /**
     * Starts application.
     * @param args 
     */
    public static void main(String[] args) { 
        Main app = new Main();
        
        /* BRANDING */
        AppSettings settings = new AppSettings(true);
        settings.setTitle("Star-Fu 101");
        settings.setSettingsDialogImage("/Textures/sf102.jpg");
        
        app.setSettings(settings);
        app.start();
    }

    /**
     * Initialising the game.
     */
    @Override
    public void simpleInitApp() {
        // Thread pool
        executor = new ScheduledThreadPoolExecutor(4);   
        
        /* PHYSICS */
        bullet      = new BulletAppState();     
        stateManager.attach(bullet);
        bullet.startPhysics();
        bullet.getPhysicsSpace().enableDebug(assetManager);   
        
        /* CAMERA */
        //flyCam.setEnabled(false);
        
        /* BEADS */
        ac = new AudioContext();
        
        
        /* ARTEMIS */
        world = new World(); 

        
        /* SEQUENCER */
        sequencerModel  = new SequencerModel();
        sequencer       = new Sequencer(ac, world);
        
        /* GAME STATES */
        menuState   = new MenuState(this, settings);
        stateManager.attach(menuState);
        
        arcadeState = new ArcadeState(this, world, ac);
        stateManager.attach(arcadeState);
        arcadeState.setEnabled(false);
        
        gridState   = new GridState(this, settings, sequencerModel);
        stateManager.attach(gridState);
        gridState.setEnabled(false);
        
        pauseState  = new PauseState(this, settings);
        stateManager.attach(pauseState);
        pauseState.setEnabled(false);
        
        /* KEYBOARD MAPPINGS */
        // KEY_RETURN -> ARCADE
        inputManager.addMapping("Arcade", arcade_trigger);
        inputManager.addListener(gameStateListener, new String[] {"Arcade"});
        
        // KEY_RSHIFT -> GRID
        inputManager.addMapping("Grid", grid_trigger);
        inputManager.addListener(gameStateListener, new String[] {"Grid"});
        
        // KEY_L -> MENU
        inputManager.addMapping("Menu", menu_trigger);
        inputManager.addListener(gameStateListener, new String[] {"Menu"});
        
        // KEY_BACK -> PAUSE
        inputManager.addMapping("Pause", pause_trigger);
        inputManager.addListener(gameStateListener, new String[] {"Pause"});

    }

    /**
     * Create game state listener and set actions
     */
    private ActionListener gameStateListener = new ActionListener() {
        public void onAction(String name, boolean isPressed, float tpf) {
            System.out.println("Pressed: " + name);
            
            /* ENABLE ARCADE STATE */
            if(name.equals("Arcade") && !isPressed) {  
//                if(!stateManager.hasState(arcadeState)) {
//                    stateManager.attach(arcadeState);
//                }
                arcadeState.setEnabled(true); 
                System.out.println("Switching to arcade...") ;
                pauseState.setEnabled(false);
                gridState.setEnabled(false);                 
                menuState.setEnabled(false);
                     }

            /* ENABLE GRID STATE */
            if(name.equals("Grid") && !isPressed) {
//                if(!stateManager.hasState(gridState)) {
//                    stateManager.attach(gridState);
//                }    
                pauseState.setEnabled(false);
                arcadeState.setEnabled(false);
                menuState.setEnabled(false);
                
                gridState.setEnabled(true);

                System.out.println("Switching to grid...") ;
                 } 
            
            /* ENABLE MENU STATE */
        if(name.equals("Menu") && !isPressed) {  
                menuState.setEnabled(true);
            
                arcadeState.setEnabled(false);
                gridState.setEnabled(false);
                pauseState.setEnabled(false);
                
                    System.out.println("Switching to menu...") ; }
        }
    };
    
    @Override
    public void simpleUpdate(float tpf) {

    }

    @Override
    public void simpleRender(RenderManager rm) {
        //TODO: add render code
    }

   
    
}
